package org.aspire.graphics;

import java.util.Vector;

import org.aspire.data.Resource;

/******************************************************************************
 * A strip is a group of related frames usually used in animation.
 * 
 * @author JPACarabuena
 *****************************************************************************/
public class Strip implements Resource {

	// ========================================================================
	// Constants
	// ========================================================================

	// ========================================================================
	// Static Methods
	// ========================================================================

	// ========================================================================
	// Fields
	// ========================================================================

	/**************************************************************************
	 * The frames for the strip.
	 *************************************************************************/
	private Vector<Frame> frames;
	
	/**************************************************************************
	 * The maximum allowed number of frames for the strip.
	 *************************************************************************/
	private int maxSize;
	
	/**************************************************************************
	 * Whether or not the frame capacity of the strip is expandable. By 
	 * enabling this, the strip can accept more frames even if it exceeds its
	 * maximum size capacity.
	 * 
	 * Default: false
	 *************************************************************************/
	private boolean expansionEnabled = false;
	
	/**************************************************************************
	 * Whether or not a frame in the strip can be changed. By enabling this,
	 * the strip can accept update on its values.
	 * 
	 * Default: false
	 *************************************************************************/
	private boolean updateEnabled = false;
	
	// ========================================================================
	// Constructors
	// ========================================================================

	/**************************************************************************
	 * Construct a new strip with the specified frames.
	 * 
	 * @param frames the frames for this strip.
	 *************************************************************************/
	public Strip(Frame[] frames) {
		this.frames = new Vector<Frame>(frames.length + 5, 5);
		this.maxSize = frames.length;
		for(int i=0; i<this.maxSize; i++) {
			this.frames.add(frames[i]);
		}
	}
	
	// ========================================================================
	// Getters & Setters
	// ========================================================================	
	
	// ========================================================================
	// Override Methods
	// ========================================================================

	// ========================================================================
	// Methods
	// ========================================================================

	/**************************************************************************
	 * Returns the frame at the specified index. If the index is out of bounds,
	 * then a null value is returned instead.
	 * 
	 * @param i	the index of the frame to be checked.
	 * @return the frame at the specified index.
	 *************************************************************************/
	public Frame getFrameAt(int i) {
		return this.frames.elementAt(i);
	}
	
	/**************************************************************************
	 * Add a frame to the strip if and only if expansion is enabled.
	 * 
	 * @param frame	the frame to be added.
	 *************************************************************************/
	public void add(Frame frame) {
		if(this.expansionEnabled) {
			this.frames.add(frame);
		}
	}
	
	/**************************************************************************
	 * Inserts a frame in the specified index if expansion is enabled and index
	 * is not out of bounds.
	 * 
	 * @param frame	the frame to be inserted.
	 * @param i the index where the frame will be inserted.
	 *************************************************************************/
	public void insertAt(Frame frame, int i) {
		if(this.expansionEnabled) {
			if(i >= 0 && i < this.frames.size()) {
				this.frames.insertElementAt(frame, i);
			}
		}
	}
	
	/**************************************************************************
	 * Delete a frame at the specified index if update is enabled and the index
	 * is not out of bounds. 
	 * 
	 * @param i	the index of the frame to be deleted.
	 *************************************************************************/
	public void delete(int i) {
		if(this.updateEnabled) {
			if(i >= 0 && i < this.frames.size()) {
				this.frames.remove(i);
			}
		}
	}
	
	/**************************************************************************
	 * Change the value of the frame at the specified index if update is
	 * enabled and the index is not out of bounds.
	 * 
	 * @param frame the new frame value.
	 * @param i the index to be updated.
	 *************************************************************************/
	public void changeAt(Frame frame, int i) {
		this.delete(i);
		this.insertAt(frame, i);
	}

	/**************************************************************************
	 * Returns the current frame count of this strip.
	 * 
	 * @return the frame count.
	 *************************************************************************/
	public int count() {
		return this.frames.size();
	}
	
	// ========================================================================
	// Inner & Anonymous Classes
	// ========================================================================
}